package com.sdp.th.netty.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.sdp.th.netty.server.NettyInitalizer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelOption;
import io.netty.channel.WriteBufferWaterMark;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioChannelOption;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.util.ResourceLeakDetector;

@Configuration
public class NettyConfig {

	@Value("${sdp.netty.bossThread}")
	private int bossThread;
	
	@Value("${sdp.netty.workerThread}")
	private int workThread;
	
	@Value("${sdp.netty.keepalive}")
	private boolean keepAlive;
	
	@Autowired
    private NettyInitalizer nettyInitalizer;
	
	@Bean(name = "bossGroup", destroyMethod = "shutdownGracefully")
    public NioEventLoopGroup bossGroup() {
        return new NioEventLoopGroup(bossThread);
    }
 
    @Bean(name = "workerGroup", destroyMethod = "shutdownGracefully")
    public NioEventLoopGroup workerGroup() {
        return new NioEventLoopGroup(workThread);
    }

    @Bean(name = "serverBootstrap")
    public ServerBootstrap bootstrap(){
        ServerBootstrap b = new ServerBootstrap();
        b.group(bossGroup(), workerGroup()).channel(NioServerSocketChannel.class).childHandler(nettyInitalizer);
        b.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
        b.option(ChannelOption.SO_BACKLOG, 1024);
        b.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
        b.childOption(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(16 * 1024, 32 * 1024));//设置高低水位(默认值)
        b.childOption(ChannelOption.SO_KEEPALIVE, keepAlive);
        b.handler(new LoggingHandler(LogLevel.DEBUG));
        ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.ADVANCED);//内存泄漏检测
        return b;
    }

}
